package com.xb.loan.encryptor.mina.server;


import com.xb.loan.encryptor.mina.conf.ServerConf;
import com.xb.loan.encryptor.mina.handler.ConfineServerHandler;
import com.xb.loan.util.SpringHelper;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

public class MinaServer {

	private static final Logger LOG = LoggerFactory.getLogger(MinaServer.class);

	private ServerConf[] serverConfArray;

	public void setServerConfArray(ServerConf[] serverConfArray) {
		this.serverConfArray = serverConfArray;
	}

	public MinaServer() {

	}

	public void start() {
		if (serverConfArray == null) {
			return;
		}

		LOG.info("[SYS] MINA is start !");

		for (ServerConf serverConf : serverConfArray) {

			NioSocketAcceptor acceptor = new NioSocketAcceptor(serverConf.getProcessorCount()<=0? Runtime.getRuntime().availableProcessors() + 1 : serverConf.getProcessorCount());
					
			acceptor.getFilterChain()
					.addLast("codec",new ProtocolCodecFilter(serverConf.getProtocolCodeFactory()));
			
			acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));

			acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
					serverConf.getBothIdle());

			acceptor.getSessionConfig().setReadBufferSize(
					serverConf.getReadBufSize());
			
			acceptor.getSessionConfig().setSendBufferSize(serverConf.getSendBufferSize());

			IoHandlerAdapter handler = serverConf.getHandler();

			if ((handler instanceof ConfineServerHandler)) {
				((ConfineServerHandler) handler).setMaxNum(serverConf
						.getConnMaxNum());
			}

			acceptor.setHandler(handler);
			
			acceptor.setReuseAddress(true);

			try {
				acceptor.bind(new InetSocketAddress(serverConf.getPort()));
			} catch (IOException e) {
				LOG.error("[SYS] port : " + serverConf.getPort()
						+ " have a Exception !", e);
			}

			LOG.info("[SYS] port : " + serverConf.getPort() + " is Start !");

		}
	}

	public static void main(String[] args) {
		SpringHelper.init("classpath:spring/minaserver.xml");
		MinaServer server = SpringHelper.getBean("serverManage");
		
		server.start();

	}

}
